package com.flowabledemo.service.impl;

import com.flowabledemo.service.CustomizedFlowService;
import org.apache.commons.lang3.ObjectUtils;
import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.validation.ProcessValidator;
import org.flowable.validation.ProcessValidatorFactory;
import org.flowable.validation.ValidationError;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author :Administrator
 * @description: TODO edit class Description
 * @create date: 2022/3/2 9:51
 */
@Service
public class CustomizedFlowServiceImpl implements CustomizedFlowService {
    @Autowired
    private RepositoryService repositoryService;

    public void createFlow(){
        BpmnModel bpmnModel=new BpmnModel();
        Process process=new Process();
        process.setId("leave-flow");
        process.setName("学生请假工作流");
        bpmnModel.addProcess(process);

        FlowElement startFlowElement=createStartFlowElement("start01","开始节点");
        FlowElement endFlowElement=createEndFlowElement("end01","结束节点");
        FlowElement teachNode = createCommonUserTask("teacher01", "数学老师节点", "tom");
        FlowElement teachNod2 = createCommonUserTask("head_teacher", "班主任节点", "Jack");
        List<FlowElement> elementList=new ArrayList<>();
        elementList.add(startFlowElement);
        elementList.add(teachNode);
        elementList.add(teachNod2);
        elementList.add(endFlowElement);


        //把节点放入process
        for (int i = 0; i <= elementList.size()-1; i++) {
            SequenceFlow sequenceFlow = new SequenceFlow(elementList.get(i).getId(), elementList.get(i+1).getId());
            process.addFlowElement(elementList.get(i));
            process.addFlowElement(sequenceFlow);
            if (i==elementList.size()-1){
                process.addFlowElement(elementList.get(i+1));
            }
        }

        //验证组装bpmnmodel是否正确
        ProcessValidator defaultProcessValidator = new ProcessValidatorFactory().createDefaultProcessValidator();
        List<ValidationError> validate = defaultProcessValidator.validate(bpmnModel);
        if(validate.size() > 0) {
            throw new RuntimeException("流程有误，请检查后重试");
        }

        String processId = process.getId();
        String fileName= processId +"_bpmn20.xml";

        new BpmnAutoLayout(bpmnModel).execute();

        Deployment deploy =repositoryService
                .createDeployment()
                .addBpmnModel(fileName,bpmnModel)
                .tenantId("d1")
                .key(processId)
                .deploy();
    }

    /**
     * 创建开始节点信息
     * @return
     */
    public FlowElement createStartFlowElement(String id,String name){
        StartEvent startEvent=new StartEvent();
        startEvent.setId(id);
        startEvent.setName(name);
        return startEvent;
    }

    /**
     * 创建结束节点信息
     * @param id
     * @param name
     * @return
     */
    public FlowElement createEndFlowElement(String id,String name){
        EndEvent endEvent=new EndEvent();
        endEvent.setId(id);
        endEvent.setName(name);
        return endEvent;
    }

    /**
     * 创建普通任务节点信息
     * @param id
     * @param name
     * @param assignee
     * @return
     */
    public FlowElement createCommonUserTask(String id,String name,String assignee){
        UserTask userTask=new UserTask();
        userTask.setId(id);
        userTask.setName(name);
        userTask.setAssignee(assignee);
        return userTask;
    }

    /**
     * 创建会签节点信息
     * @param id
     * @param name
     * @return
     */
    public FlowElement createMultiUserTask(String id,String name){
        UserTask userTask=new UserTask();
        userTask.setId(id);
        userTask.setName(name);
        //分配用户
        userTask.setAssignee("${assignee}");
        MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics=new MultiInstanceLoopCharacteristics();
//        multiInstanceLoopCharacteristics.setCollectionString("${collectionList}");
        //完成条件,默认所有人都完成
        multiInstanceLoopCharacteristics.setCompletionCondition("${completionCondition}");
        //元素变量多实例,一般和设置的assignee变量是对应的
        multiInstanceLoopCharacteristics.setElementVariable("assignee");
        //集合多实例,用于接收集合数据的表达式
        multiInstanceLoopCharacteristics.setInputDataItem("${itemList}");
        userTask.setLoopCharacteristics(multiInstanceLoopCharacteristics);
        return userTask;


    }

    /**
     * 绘制节点流转顺序
     * @param id
     * @param name
     * @param targetId
     * @param sourceId
     * @param conditionExpression
     * @return
     */
    public SequenceFlow createSequeneFlow(String id,String name,String sourceId,String targetId,String conditionExpression){
        SequenceFlow sequenceFlow=new SequenceFlow();
        sequenceFlow.setId(id);
        sequenceFlow.setName(name);
        if (ObjectUtils.isNotEmpty(targetId)){
            sequenceFlow.setTargetRef(targetId);
        }
        if (ObjectUtils.isNotEmpty(sourceId)){
            sequenceFlow.setSourceRef(sourceId);
        }
        if (ObjectUtils.isNotEmpty(conditionExpression)){
            sequenceFlow.setConditionExpression(conditionExpression);
        }
        return sequenceFlow;
    }
}
